package aupdg.presentation;

import aupdg.data.DirectedGraphCustom;
import aupdg.presentation.adapter.LdgToJPanel;
import aupdg.presentation.adapter.impl.LdgToDirectedGraphImpl;
import aupdg.data.model.Edge;
import aupdg.data.model.Ldg;
import aupdg.data.model.Node;
import aupdg.data.model.impl.AuControlDependenceEdge;
import aupdg.data.model.impl.AuEntryNode;
import aupdg.data.model.impl.AuLdg;
import aupdg.data.model.impl.AuTransitionNode;
import edu.uci.ics.jung.algorithms.layout.LDGLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import java.awt.*;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import org.apache.commons.collections15.Transformer;

/**
 * The following class initializes the JUNG library when AuLDG starts, by
 * creating this small sample LDG that is shown as background of the graph
 * panel.
 *
 * @author AA and CJ
 */
public class SampleLdgToJPanelImpl implements LdgToJPanel {

    private GraphZoomScrollPane zoomPanel;

    /**
     * Constructor. It constructs a GraphZoomScrollPane from the LDG.
     *
     * @param gm
     */
    public SampleLdgToJPanelImpl(DefaultModalGraphMouse gm) {
        // TODO
        //this.setLayout(new BorderLayout());
        //this.removeAll();

        Node entryNode = new AuEntryNode();
        Node lNode = new AuTransitionNode("L");
        Node dNode = new AuTransitionNode("D");
        Node gNode = new AuTransitionNode("G");

        Edge edge0 = new AuControlDependenceEdge(entryNode, lNode, "EL");
        Edge edge1 = new AuControlDependenceEdge(lNode, dNode, "LD");
        Edge edge2 = new AuControlDependenceEdge(lNode, gNode, "LG");

        Ldg ldg = new AuLdg();
        ldg.addNode(entryNode);
        ldg.addNode(lNode);
        ldg.addNode(dNode);
        ldg.addNode(gNode);
        ldg.addEdge(0, edge0);
        ldg.addEdge(1, edge1);
        ldg.addEdge(1, edge2);

        final DirectedGraphCustom graph = new LdgToDirectedGraphImpl().convert(ldg);
        Layout<Node, Edge> layout = new LDGLayout<Node, Edge>(graph);
        layout.setSize(new Dimension(500, 400));
        VisualizationViewer<Node, Edge> vv = new VisualizationViewer<Node, Edge>(
                layout) {

            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                // Draw the background image.
                try {
                    g.drawImage(ImageIO.read(this.getClass().getClassLoader().getResource("aupdg/presentation/resources/graphPanelBackground.png")), 0, 0, null);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };

        zoomPanel = new GraphZoomScrollPane(vv);

        vv.setBackground(Color.white);
        // Show vertex and edge labels
        vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
        vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller());

        //set stroke of edges
        float dash[] = {10.0f};
        final Stroke edgeStroke = new BasicStroke(1.0f, BasicStroke.CAP_BUTT,
                BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f);
        final Stroke edgeDefStroke = new BasicStroke();
        Transformer<Edge, Stroke> edgeStrokeTransformer = new Transformer<Edge, Stroke>() {

            @Override
            public Stroke transform(Edge e) {
                if (graph.isDataEdge(e)) { //TODO CJC change here, check for data dependence edges and choose dash lines
                    return edgeStroke;
                } else {
                    return edgeDefStroke;
                }
            }
        };
        vv.getRenderContext().setEdgeStrokeTransformer(edgeStrokeTransformer);
        vv.setGraphMouse(gm);
        vv.revalidate();
        vv.repaint();

        gm.setMode(ModalGraphMouse.Mode.EDITING);
    }

    @Override
    public JPanel renderLdg() {
        zoomPanel.setOpaque(false);
        zoomPanel.revalidate();
        zoomPanel.repaint();
        zoomPanel.setVisible(true);
        return zoomPanel;
    }
}
